package com.peppa.sirius.esaml.design;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.sirius.viewpoint.DSemanticDecorator;

import com.peppa.xtext.esaml.esaml.AbstractModel;
import com.peppa.xtext.esaml.esaml.AccessChannel;
import com.peppa.xtext.esaml.esaml.AccessFeature;
import com.peppa.xtext.esaml.esaml.ActivityImpl;
import com.peppa.xtext.esaml.esaml.ActivitySubComponent;
import com.peppa.xtext.esaml.esaml.ActivityType;
import com.peppa.xtext.esaml.esaml.AddressBinding;
import com.peppa.xtext.esaml.esaml.ComponentImpl;
import com.peppa.xtext.esaml.esaml.ComponentType;
import com.peppa.xtext.esaml.esaml.DataComponentImpl;
import com.peppa.xtext.esaml.esaml.DataComponentType;
import com.peppa.xtext.esaml.esaml.DataSubComponent;
import com.peppa.xtext.esaml.esaml.EnumVariable;
import com.peppa.xtext.esaml.esaml.Feature;
import com.peppa.xtext.esaml.esaml.MonitorImpl;
import com.peppa.xtext.esaml.esaml.MonitorSubComponent;
import com.peppa.xtext.esaml.esaml.MonitorType;
import com.peppa.xtext.esaml.esaml.PortChannel;
import com.peppa.xtext.esaml.esaml.PortFeature;
import com.peppa.xtext.esaml.esaml.Reference;
import com.peppa.xtext.esaml.esaml.ReferenceEnum;
import com.peppa.xtext.esaml.esaml.SelfAccessChannel;
import com.peppa.xtext.esaml.esaml.SelfPortChannel;
import com.peppa.xtext.esaml.esaml.StateImpl;
import com.peppa.xtext.esaml.esaml.StateSubComponent;
import com.peppa.xtext.esaml.esaml.StateType;
import com.peppa.xtext.esaml.esaml.SubComponent;
import com.peppa.xtext.esaml.esaml.SubSystemImpl;
import com.peppa.xtext.esaml.esaml.SubSystemSubComponent;
import com.peppa.xtext.esaml.esaml.SubSystemType;
import com.peppa.xtext.esaml.esaml.SystemImpl;
import com.peppa.xtext.esaml.esaml.SystemType;
import com.peppa.xtext.esaml.esaml.TimeTriggerImpl;
import com.peppa.xtext.esaml.esaml.TimeTriggerSubComponent;
import com.peppa.xtext.esaml.esaml.TimeTriggerType;
import com.peppa.xtext.esaml.esaml.Variable;
import com.peppa.xtext.esaml.esaml.impl.AccessChannelImpl;
import com.peppa.xtext.esaml.esaml.impl.AccessFeatureImpl;
import com.peppa.xtext.esaml.esaml.impl.ActivityImplImpl;
import com.peppa.xtext.esaml.esaml.impl.ActivityInteractionsImpl;
import com.peppa.xtext.esaml.esaml.impl.ActivitySubComponentImpl;
import com.peppa.xtext.esaml.esaml.impl.ActivityTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.AddressBindingImpl;
import com.peppa.xtext.esaml.esaml.impl.BASE_TYPEImpl;
import com.peppa.xtext.esaml.esaml.impl.CompositeTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.DataComponentImplImpl;
import com.peppa.xtext.esaml.esaml.impl.DataComponentTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.EnumTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.EnumVariableImpl;
import com.peppa.xtext.esaml.esaml.impl.FeatureImpl;
import com.peppa.xtext.esaml.esaml.impl.ModelImpl;
import com.peppa.xtext.esaml.esaml.impl.MonitorImplImpl;
import com.peppa.xtext.esaml.esaml.impl.MonitorSubComponentImpl;
import com.peppa.xtext.esaml.esaml.impl.MonitorTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.PortChannelImpl;
import com.peppa.xtext.esaml.esaml.impl.PortFeatureImpl;
import com.peppa.xtext.esaml.esaml.impl.ReferenceEnumImpl;
import com.peppa.xtext.esaml.esaml.impl.ReferenceImpl;
import com.peppa.xtext.esaml.esaml.impl.ScheduleImpl;
import com.peppa.xtext.esaml.esaml.impl.SelfAccessChannelImpl;
import com.peppa.xtext.esaml.esaml.impl.SelfPortChannelImpl;
import com.peppa.xtext.esaml.esaml.impl.StateImplImpl;
import com.peppa.xtext.esaml.esaml.impl.StateMachineImpl;
import com.peppa.xtext.esaml.esaml.impl.StateSubComponentImpl;
import com.peppa.xtext.esaml.esaml.impl.StateTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.SubSystemImplImpl;
import com.peppa.xtext.esaml.esaml.impl.SubSystemSubComponentImpl;
import com.peppa.xtext.esaml.esaml.impl.SubSystemTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.SystemImplImpl;
import com.peppa.xtext.esaml.esaml.impl.SystemTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.TimeTriggerImplImpl;
import com.peppa.xtext.esaml.esaml.impl.TimeTriggerSubComponentImpl;
import com.peppa.xtext.esaml.esaml.impl.TimeTriggerTypeImpl;
import com.peppa.xtext.esaml.esaml.impl.VariableImpl;
import com.peppa.xtext.esaml.esaml.impl.VariableTypeImpl;

/**
 * The services class used by VSM.
 */
public class Services {
    
    /**
    * See http://help.eclipse.org/neon/index.jsp?topic=%2Forg.eclipse.sirius.doc%2Fdoc%2Findex.html&cp=24 for documentation on how to write service methods.
    */
    public EObject myService(EObject self, String arg) {
       // TODO Auto-generated code
      return self;
    }
    
    /**
     * 获取属性中变量的名字与类型
     * @param self
     * @return
     */
    public String getVariable_Name_Type(Variable self) {
    	VariableImpl variableImpl = (VariableImpl) self;
		StringBuilder typeString = new StringBuilder(variableImpl.getName());
		VariableTypeImpl variableTypeImpl = (VariableTypeImpl) variableImpl.getVariableType();
		EObject type = variableTypeImpl.getType(); 
		if(type instanceof BASE_TYPEImpl) {
			typeString.append(":" + ((BASE_TYPEImpl) type).getTypeName());
		}else if(type instanceof CompositeTypeImpl){
			DataComponentTypeImpl dataComponentTypeImpl = (DataComponentTypeImpl) ((CompositeTypeImpl) type).getDataComponentType();
			typeString.append(":" + dataComponentTypeImpl.getName());
		}
		if(variableTypeImpl.isIsArray()) {
			int length = variableTypeImpl.getLength();
			if(length==0) typeString.append("[]");
			else typeString.append("["+length+"]");
		}
 		
		return typeString.toString();
	}
    
    /**
     * 获取属性中枚举变量的名字与类型
     * @param self
     * @return
     */
    public String getEnumVariable_Name_Type(EnumVariable self) {
    	StringBuilder typeString = new StringBuilder(self.getName());
    	EnumVariableImpl enumVariableImpl = (EnumVariableImpl) self;
    	EnumTypeImpl enumTypeImpl = (EnumTypeImpl) enumVariableImpl.getEnumType();
    	typeString.append(" : enum "+enumTypeImpl.getName());
		return typeString.toString();
    }
    
    /**
     * 获取属性中引用的名字与类型
     * @param self
     * @return
     */
    public String getReference_Name_Type(Reference self) {
    	StringBuilder reStringBuilder = new StringBuilder(self.getRefName().toString());
    	ReferenceImpl referenceImpl = (ReferenceImpl) self;
    	EObject refTypeEObject = referenceImpl.getRefVariableType();
    	if(refTypeEObject instanceof EnumTypeImpl) {
    		EnumTypeImpl enumTypeImpl = (EnumTypeImpl) refTypeEObject;
    		reStringBuilder.append(enumTypeImpl.getName());
    	}else if(refTypeEObject instanceof VariableTypeImpl){
    		VariableTypeImpl variableTypeImpl = (VariableTypeImpl) refTypeEObject;
    		EObject type = variableTypeImpl.getType(); 
    		if(type instanceof BASE_TYPEImpl) {
    			reStringBuilder.append(":" + ((BASE_TYPEImpl) type).getTypeName());
    		}else if(type instanceof CompositeTypeImpl){
    			reStringBuilder.append(":" + ((CompositeTypeImpl) type).getDataComponentType().getName());
    		}
    		if(variableTypeImpl.isIsArray()) {
    			int length = variableTypeImpl.getLength();
    			if(length==0) reStringBuilder.append("[]");
    			else reStringBuilder.append("["+length+"]");
    		}
		}
    	return reStringBuilder.toString();
    }
    
    /**
     * 获取引用枚举的名字与类型
     * @param self
     * @return
     */
    public String getReferenceEnum_Name_Type(ReferenceEnum self) {
    	StringBuilder reStringBuilder = new StringBuilder(self.getRefName().toString());
    	ReferenceEnumImpl referenceImpl = (ReferenceEnumImpl) self;
    	EnumTypeImpl refEnumTypeImpl = (EnumTypeImpl) referenceImpl.getRefEnumType();
    	reStringBuilder.append(" : enum " + refEnumTypeImpl.getName());
    	
    	return reStringBuilder.toString();
    }
    
    /**
     * 获取所有SystemType的实现
     * @param self
     * @return
     */
    public List<SystemImpl> getSystemTypeImpls(SystemType self){
    	List<SystemImpl> res = new ArrayList<SystemImpl>();
    	SystemTypeImpl systemTypeImpl = (SystemTypeImpl) self;
    	EObject eContainer = systemTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof SystemImplImpl) {
    			SystemImplImpl systemImplImpl = (SystemImplImpl) abstractModel;
        		if(systemImplImpl.getOwnedRealization().equals(self)) res.add((SystemImpl) systemImplImpl);
        	}
    	}	
    	return res;
    }
    
    /**
     * 获取SubSystemType的所有实现
     * @param self
     * @return
     */
    public List<SubSystemImpl> getSubSystemTypeImpls(SubSystemType self){
    	List<SubSystemImpl> res = new ArrayList<SubSystemImpl>();
    	SubSystemTypeImpl subSystemTypeImpl = (SubSystemTypeImpl) self;
    	EObject eContainer = subSystemTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof SubSystemImplImpl) {
    			SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) abstractModel;
        		if(subSystemImplImpl.getOwnedRealization().equals(self)) res.add((SubSystemImpl) subSystemImplImpl);
        	}
    	}	
    	return res;
    }
    
    /**
     * 获取ActivityType的所有实现
     * @param self
     * @return
     */
    public List<ActivityImpl> getActivityTypeImpls(ActivityType self){
    	List<ActivityImpl> res = new ArrayList<ActivityImpl>();
    	ActivityTypeImpl activityTypeImpl = (ActivityTypeImpl) self;
    	EObject eContainer = activityTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof ActivityImplImpl) {
        		ActivityImplImpl activityImplImpl = (ActivityImplImpl) abstractModel;
        		if(activityImplImpl.getOwnedRealization().equals(self)) res.add((ActivityImpl) activityImplImpl);
        	}
    	}
    	return res;
    }
    
    /**
     * 获取StateType的所有实现
     * @param self
     * @return
     */
    public List<StateImpl> getStateTypeImpls(StateType self){
    	List<StateImpl> res = new ArrayList<StateImpl>();
    	StateTypeImpl stateTypeImpl = (StateTypeImpl) self;
    	EObject eContainer = stateTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof StateImplImpl) {
    			StateImplImpl stateImplImpl = (StateImplImpl) abstractModel;
        		if(stateImplImpl.getOwnedRealization().equals(self)) res.add((StateImpl) stateImplImpl);
        	}
    	}
    	return res;
    }
    
    /**
     * 获取TimeTriggerType的所有实现
     * @param self
     * @return
     */
    public List<TimeTriggerImpl> getTimeTriggerTypeImpls(TimeTriggerType self){
    	List<TimeTriggerImpl> res = new ArrayList<TimeTriggerImpl>();
    	TimeTriggerTypeImpl timeTriggerTypeImpl = (TimeTriggerTypeImpl) self;
    	EObject eContainer = timeTriggerTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof TimeTriggerImplImpl) {
    			TimeTriggerImplImpl timeTriggerImplImpl = (TimeTriggerImplImpl) abstractModel;
        		if(timeTriggerImplImpl.getOwnedRealization().equals(self)) res.add((TimeTriggerImplImpl) timeTriggerImplImpl);
        	}
    	}
    	return res;
    }
    
    /**
     * 获取MonitorType的所有实现
     * @param self
     * @return
     */
    public List<MonitorImpl> getMonitorTypeImpls(MonitorType self){
    	List<MonitorImpl> res = new ArrayList<MonitorImpl>();
    	MonitorTypeImpl monitorTypeImpl = (MonitorTypeImpl) self;
    	EObject eContainer = monitorTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof MonitorImplImpl) {
    			MonitorImplImpl monitorImplImpl = (MonitorImplImpl) abstractModel;
        		if(monitorImplImpl.getOwnedRealization().equals(self)) res.add((MonitorImplImpl) monitorImplImpl);
        	}
    	}
    	return res;
    }
    
    /**
     * 获取DataComponentType的所有实现
     * @param self
     * @return
     */
    public List<DataComponentImpl> getDataComponentTypeImpls(DataComponentType self){
    	List<DataComponentImpl> res = new ArrayList<>();
    	DataComponentTypeImpl dataComponentTypeImpl = (DataComponentTypeImpl) self;
    	EObject eContainer = dataComponentTypeImpl.eContainer();
    	ModelImpl modelImpl = (ModelImpl) eContainer;
    	EList<AbstractModel> abstractModels  = modelImpl.getAbstractModel();
    	for(AbstractModel abstractModel : abstractModels) {
    		if(abstractModel instanceof DataComponentImplImpl) {
    			DataComponentImplImpl dataComponentImplImpl = (DataComponentImplImpl) abstractModel;
        		if(dataComponentImplImpl.getOwnedRealization().equals(self)) res.add((DataComponentImpl) dataComponentImplImpl);
        	}
    	}
    	return res;
    }
    
    /**
     * 获取SystemImpl中的所有SubSystem子组件
     * @param self
     * @return
     */
    public List<SubSystemSubComponent> getSubsystemSubComponents(SystemImpl self){
    	EList<SubSystemSubComponent> list = ((SystemImplImpl) self).getOwnedSubSystemSubComponent();
    	
    	return list;
    }
    
    /**
     * 获取SystemImpl中的所有TimeTrigger子组件
     * @param self
     * @return
     */
    public List<TimeTriggerSubComponent> getTimeTriggerSubComponents(SystemImpl self){
    	EList<TimeTriggerSubComponent> list = ((SystemImplImpl) self).getOwnedTimeTriggerSubComponent();
    	return list;
    }
    
    /**
     * 获取SystemImpl中的所有Monitor子组件
     * @param self
     * @return
     */
    public List<MonitorSubComponent> getMonitorSubComponents(SystemImpl self){
    	EList<MonitorSubComponent> list = ((SystemImplImpl) self).getOwnedMonitorSubComponent();
    	return list;
    }
    
    /**
     * 获取SystemImpl或SubSystemImpl中所有的Data子组件
     * @param self
     * @return
     */
    public List<SubComponent> getDataSubComponents(ComponentImpl self){
    	List<SubComponent> res = new ArrayList<>();
    	EList<DataSubComponent> list = null;
    	if(self instanceof SystemImplImpl) {
    		list = ((SystemImplImpl) self).getOwnedDataSubComponent();
    	}else if(self instanceof SubSystemImplImpl) {
    		ActivityInteractionsImpl activityInteractionsImpl  = (ActivityInteractionsImpl) ((SubSystemImplImpl) self).getActivityInteractions();
    		list = activityInteractionsImpl.getOwnedDataSubComponent();
    	}
    	
    	for(DataSubComponent subSystemComponent : list) {
    		res.add((SubComponent)subSystemComponent);
    	}
    	return res;
    }
    
    /**
     * 获取SubSystemImpl中的所有Activity子组件
     * @param self
     * @return
     */
    public List<ActivitySubComponent> getActivitySubComponents(SubSystemImpl self){
    	ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) ((SubSystemImplImpl) self).getActivityInteractions();
    	EList<ActivitySubComponent> activitySubComponentlist = activityInteractionsImpl.getOwnedActivitySubComponent();
		return activitySubComponentlist;
    	
    }
    
    /**
     * 获取ActivityImpl中的所有State子组件
     * @param self
     * @return
     */
    public List<StateSubComponent> getStateSubComponents(ActivityImpl self){
    	ActivityImplImpl activityImplImpl = (ActivityImplImpl) self;
    	StateMachineImpl stateMachineImpl = (StateMachineImpl) activityImplImpl.getStateMachine();
    	if(stateMachineImpl == null) return null;
    	EList<StateSubComponent> stateSubComponents = stateMachineImpl.getOwnedStateSubComponent();
		return stateSubComponents;
    }
    
    /**
     * 获取ComponentType的某种端口
     * @param self
     * @param portDirection
     * @param portType
     * @return
     */
    public List<PortFeature> getPort(ComponentType self, String portDirection, String portType){
    	List<PortFeature> res = new ArrayList<>();
    	EList<Feature> features = null;
    	if(self instanceof SystemTypeImpl) {
    		features = ((SystemTypeImpl) self).getFeatures();
    	}else if (self instanceof SubSystemTypeImpl) {
    		features = ((SubSystemTypeImpl) self).getFeatures();
		}else if (self instanceof ActivityTypeImpl) {
			features = ((ActivityTypeImpl) self).getFeatures();
		}else if (self instanceof TimeTriggerTypeImpl) {
			features = ((TimeTriggerTypeImpl) self).getFeatures();
		}else if (self instanceof MonitorTypeImpl) {
			features = ((MonitorTypeImpl) self).getFeatures();
		}
    	
    	for(Feature feature : features) {
    		FeatureImpl featureImpl = (FeatureImpl) feature;
    		if(featureImpl instanceof PortFeatureImpl) {
    			PortFeatureImpl portFeatureImpl = (PortFeatureImpl) featureImpl;
//    			System.out.println(portFeatureImpl.getType().toString());
    			if(portDirection.equals(portFeatureImpl.getPortDirection()) && portType.equals(portFeatureImpl.getType().toString())) {
        			res.add((PortFeature) portFeatureImpl);
        		}
    		}
    		
    	}
    	return res;
    }
    
    /**
     * 获取SubComponent的某种端口
     * @param self
     * @param portDirection
     * @param portType
     * @return
     */
    public List<PortFeature> getSubComponentPort(SubComponent self, String portDirection, String portType) {
    	List<PortFeature> res = new ArrayList<>();
    	EList<Feature> features = null;
    	if(self instanceof SubSystemSubComponentImpl) {
    		SubSystemSubComponentImpl subSystemSubComponentImpl = (SubSystemSubComponentImpl) self;
    		SubSystemTypeImpl subSystemTypeImpl = (SubSystemTypeImpl) subSystemSubComponentImpl.getSubSystemSubComponentType();
    		features = subSystemTypeImpl.getFeatures();
    	}else if(self instanceof ActivitySubComponentImpl) {
    		ActivitySubComponentImpl activitySubComponentImpl = (ActivitySubComponentImpl) self;
    		ActivityTypeImpl activityTypeImpl = (ActivityTypeImpl) activitySubComponentImpl.getActivitySubComponentType();
    		features = activityTypeImpl.getFeatures();
    	}else if(self instanceof TimeTriggerSubComponentImpl) {
    		TimeTriggerSubComponentImpl timeTriggerSubComponentImpl = (TimeTriggerSubComponentImpl) self;
    		TimeTriggerTypeImpl timeTriggerTypeImpl = (TimeTriggerTypeImpl) timeTriggerSubComponentImpl.getTimeTriggerSubComponentType();
    		features = timeTriggerTypeImpl.getFeatures();
    	}else if(self instanceof MonitorSubComponentImpl) {
    		MonitorSubComponentImpl monitorSubComponentImpl = (MonitorSubComponentImpl) self;
    		MonitorTypeImpl monitorTypeImpl = (MonitorTypeImpl) monitorSubComponentImpl.getMonitorSubComponentType();
    		features = monitorTypeImpl.getFeatures();
    	}
    	
    	for(Feature feature : features) {
    		FeatureImpl featureImpl = (FeatureImpl) feature;
    		if(featureImpl instanceof PortFeatureImpl) {
    			PortFeatureImpl portFeatureImpl = (PortFeatureImpl) featureImpl;
//    			System.out.println(portFeatureImpl.getType().toString());
    			if(portDirection.equals(portFeatureImpl.getPortDirection()) && portType.equals(portFeatureImpl.getType().toString())) {
        			res.add((PortFeature) portFeatureImpl);
        		}
    		}
    		
    	}
    	return res;
    }
    
    /**
     * 获取ComponentType的某种Access
     * @param self
     * @param accessDirection
     * @return
     */
    public List<AccessFeature> getAccess(ComponentType self, String accessDirection){
    	List<AccessFeature> res = new ArrayList<>();
    	EList<Feature> features = null;
    	if(self instanceof SystemTypeImpl) {
    		features = ((SystemTypeImpl) self).getFeatures();
    	}else if (self instanceof SubSystemTypeImpl) {
    		features = ((SubSystemTypeImpl) self).getFeatures();
		}else if (self instanceof ActivityTypeImpl) {
			features = ((ActivityTypeImpl) self).getFeatures();
		}else if (self instanceof TimeTriggerTypeImpl) {
			features = ((TimeTriggerTypeImpl) self).getFeatures();
		}else if (self instanceof MonitorTypeImpl) {
			features = ((MonitorTypeImpl) self).getFeatures();
		}

    	for(Feature feature : features) {
    		FeatureImpl featureImpl = (FeatureImpl) feature;
    		if(featureImpl instanceof AccessFeatureImpl) {
    			AccessFeatureImpl portFeatureImpl = (AccessFeatureImpl) featureImpl;
    			if(accessDirection.equals(portFeatureImpl.getAccessDirection())) {
        			res.add((AccessFeature) featureImpl);
        		}
    		}
    		
    	}
    	return res;
    }
    
    /**
     * 获取SubComponent的某种Access
     * @param self
     * @param accessDirection
     * @return
     */
    public List<AccessFeature> getSubComponentAccess(SubComponent self, String accessDirection){
    	List<AccessFeature> res = new ArrayList<>();
    	EList<Feature> features = null;
    	if(self instanceof SubSystemSubComponentImpl) {
    		SubSystemSubComponentImpl subSystemSubComponentImpl = (SubSystemSubComponentImpl) self;
    		SubSystemTypeImpl subSystemTypeImpl = (SubSystemTypeImpl) subSystemSubComponentImpl.getSubSystemSubComponentType();
    		features = subSystemTypeImpl.getFeatures();
    	}else if(self instanceof ActivitySubComponentImpl) {
    		ActivitySubComponentImpl activitySubComponentImpl = (ActivitySubComponentImpl) self;
    		ActivityTypeImpl activityTypeImpl = (ActivityTypeImpl) activitySubComponentImpl.getActivitySubComponentType();
    		features = activityTypeImpl.getFeatures();
    	}else if(self instanceof TimeTriggerSubComponentImpl) {
    		TimeTriggerSubComponentImpl timeTriggerSubComponentImpl = (TimeTriggerSubComponentImpl) self;
    		TimeTriggerTypeImpl timeTriggerTypeImpl = (TimeTriggerTypeImpl) timeTriggerSubComponentImpl.getTimeTriggerSubComponentType();
    		features = timeTriggerTypeImpl.getFeatures();
    	}else if(self instanceof MonitorSubComponentImpl) {
    		MonitorSubComponentImpl monitorSubComponentImpl = (MonitorSubComponentImpl) self;
    		MonitorTypeImpl monitorTypeImpl = (MonitorTypeImpl) monitorSubComponentImpl.getMonitorSubComponentType();
    		features = monitorTypeImpl.getFeatures();
    	}

    	for(Feature feature : features) {
    		FeatureImpl featureImpl = (FeatureImpl) feature;
    		if(featureImpl instanceof AccessFeatureImpl) {
    			AccessFeatureImpl portFeatureImpl = (AccessFeatureImpl) featureImpl;
    			if(accessDirection.equals(portFeatureImpl.getAccessDirection())) {
        			res.add((AccessFeature) featureImpl);
        		}
    		}
    		
    	}
    	return res;
    }
    
    /**
     * 创建SelfPortChannel的前提条件
     * 	1. SelfPortChannel两端的图形需要同属于一个容器(二者同时属于一个容器)
     * 	2. SelfPortChannel与两端的图形也要同属于一个容器(三者同时属于一个容器)
     * @param self
     * @param sourceView
     * @param targetView
     * @return
     */
    public Boolean getPreconditionsCreateSelfPortChannel(SelfPortChannel self, DSemanticDecorator sourceView, DSemanticDecorator targetView){
    	SelfPortChannelImpl selfPortChannelImpl = (SelfPortChannelImpl) self;
		Boolean condition1 = false;
		Boolean condition2 = false;
    	if(selfPortChannelImpl.eContainer() instanceof SystemImplImpl) {
    		if(selfPortChannelImpl.getSourceSubComponent() == null) {
    			condition1 = sourceView.eContainer()==targetView.eContainer().eContainer();
    			SystemImplImpl systemImplImpl = (SystemImplImpl) selfPortChannelImpl.eContainer();
    			condition2 = sourceView.eContainer().toString().equals(systemImplImpl.getName());
    		}else {
    			condition1 = sourceView.eContainer().eContainer()==targetView.eContainer();
    			SystemImplImpl systemImplImpl = (SystemImplImpl) selfPortChannelImpl.eContainer();
    			condition2 = sourceView.eContainer().eContainer().toString().equals(systemImplImpl.getName());
    		}
        	return condition1&&condition2;
    	}else if(selfPortChannelImpl.eContainer() instanceof ActivityInteractionsImpl) {
    		if(selfPortChannelImpl.getSourceSubComponent() == null) {
//    			System.out.println(sourceView.eContainer());
//    			System.out.println(targetView.eContainer().eContainer());
//    			System.out.println(sourceView.eContainer().toString());
    			condition1 = sourceView.eContainer()==targetView.eContainer().eContainer();
    			ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) selfPortChannelImpl.eContainer();
    			SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) activityInteractionsImpl.eContainer();
    			condition2 = sourceView.eContainer().toString().equals(subSystemImplImpl.getName());
    		}else {
//    			System.out.println(sourceView.eContainer().eContainer());
//    			System.out.println(targetView.eContainer());
//    			System.out.println(sourceView.eContainer().eContainer().toString());
    			condition1 = sourceView.eContainer().eContainer()==targetView.eContainer();
    			ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) selfPortChannelImpl.eContainer();
    			SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) activityInteractionsImpl.eContainer();
    			condition2 = sourceView.eContainer().eContainer().toString().equals(subSystemImplImpl.getName());
    		}
        	return condition1&&condition2;
    	}
    	
    	System.out.println("获取创建SelfPortChannel的前提条件出现问题");
    	return false;
    }
    
    /**
     * 创建PortChannel的前提条件
     * 	1. PortChannel两端的图形需要同属于一个容器(二者同时属于一个容器)
     * 	2. PortChannel与两端的图形也要同属于一个容器(三者同时属于一个容器)
     * @param self
     * @param sourceView
     * @param targetView
     * @return
     */
    public Boolean getPreconditionsCreatePortChannel(PortChannel self, DSemanticDecorator sourceView, DSemanticDecorator targetView){
    	PortChannelImpl portChannelImpl = (PortChannelImpl) self;
//    	System.out.println(self.eContainer());
//    	System.out.println(portChannelImpl.eContainer());
//    	System.out.println(sourceView.eContainer().eContainer());
    	if(portChannelImpl.eContainer() instanceof SystemImplImpl) {
    		Boolean condition1 = sourceView.eContainer().eContainer()==targetView.eContainer().eContainer();
        	SystemImplImpl systemImplImpl = (SystemImplImpl) portChannelImpl.eContainer();
        	Boolean condition2 = sourceView.eContainer().eContainer().toString().equals(systemImplImpl.getName());
        	return condition1&&condition2;
    	}else if(portChannelImpl.eContainer() instanceof ActivityInteractionsImpl) {
    		Boolean condition1 = sourceView.eContainer().eContainer()==targetView.eContainer().eContainer();
    		ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) portChannelImpl.eContainer();
    		SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) activityInteractionsImpl.eContainer();
        	Boolean condition2 = sourceView.eContainer().eContainer().toString().equals(subSystemImplImpl.getName());
        	return condition1&&condition2;
    	}
    	
    	System.out.println("获取创建PortChannel的前提条件出现问题");
    	return false;
    }
    
    /**
     * 创建SelfAccessChannel的前提条件
     * 	1. SelfAccessChannel两端的图形需要同属于一个容器(二者同时属于一个容器)
     * 	2. SelfAccessChannel与两端的图形也要同属于一个容器(三者同时属于一个容器) 
     * @param self
     * @param sourceView
     * @param targetView
     * @return
     */
    public Boolean getPreconditionsCreateSelfAccessChannel(SelfAccessChannel self, DSemanticDecorator sourceView, DSemanticDecorator targetView){
    	SelfAccessChannelImpl selfAccessChannelImpl = (SelfAccessChannelImpl) self;
		Boolean condition1 = false;
		Boolean condition2 = false;
    	if(selfAccessChannelImpl.eContainer() instanceof SystemImplImpl) {
    		if(selfAccessChannelImpl.getSourceSubComponent() == null) {
    			condition1 = sourceView.eContainer()==targetView.eContainer().eContainer();
    			SystemImplImpl systemImplImpl = (SystemImplImpl) selfAccessChannelImpl.eContainer();
    			condition2 = sourceView.eContainer().toString().equals(systemImplImpl.getName());
    		}else {
    			condition1 = sourceView.eContainer().eContainer()==targetView.eContainer();
    			SystemImplImpl systemImplImpl = (SystemImplImpl) selfAccessChannelImpl.eContainer();
    			condition2 = sourceView.eContainer().eContainer().toString().equals(systemImplImpl.getName());
    		}
        	return condition1&&condition2;
    	}else if(selfAccessChannelImpl.eContainer() instanceof ActivityInteractionsImpl) {
    		if(selfAccessChannelImpl.getSourceSubComponent() == null) {
//    			System.out.println(sourceView.eContainer());
//    			System.out.println(targetView.eContainer().eContainer());
//    			System.out.println(sourceView.eContainer().toString());
    			condition1 = sourceView.eContainer()==targetView.eContainer().eContainer();
    			ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) selfAccessChannelImpl.eContainer();
    			SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) activityInteractionsImpl.eContainer();
    			condition2 = sourceView.eContainer().toString().equals(subSystemImplImpl.getName());
    		}else {
//    			System.out.println(sourceView.eContainer().eContainer());
//    			System.out.println(targetView.eContainer());
//    			System.out.println(sourceView.eContainer().eContainer().toString());
    			condition1 = sourceView.eContainer().eContainer()==targetView.eContainer();
    			ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) selfAccessChannelImpl.eContainer();
    			SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) activityInteractionsImpl.eContainer();
    			condition2 = sourceView.eContainer().eContainer().toString().equals(subSystemImplImpl.getName());
    		}
        	return condition1&&condition2;
    	}
    	System.out.println("获取创建SelfAccessChannel的前提条件出现问题");
    	return false;
    }
    
    /**
     * 创建AccessChannel的前提条件
     * 	1. AccessChannel两端的图形需要同属于一个容器
     * 	2. AccessChannel与两端的图形也要同属于一个容器 
     * @param self
     * @param sourceView
     * @param targetView
     * @return
     */
    public Boolean getPreconditionsCreateAccessChannel(AccessChannel self, DSemanticDecorator sourceView, DSemanticDecorator targetView){
    	AccessChannelImpl accessChannelImpl = (AccessChannelImpl) self;
    	
    	if(accessChannelImpl.eContainer() instanceof SystemImplImpl) {
    		Boolean condition1 = sourceView.eContainer().eContainer()==targetView.eContainer();
        	SystemImplImpl systemImplImpl = (SystemImplImpl) accessChannelImpl.eContainer();
        	Boolean condition2 = sourceView.eContainer().eContainer().toString().equals(systemImplImpl.getName());
        	return condition1&&condition2;
    	}else if(accessChannelImpl.eContainer() instanceof ActivityInteractionsImpl) {
    		Boolean condition1 = sourceView.eContainer().eContainer()==targetView.eContainer();
    		ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) accessChannelImpl.eContainer();
    		SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) activityInteractionsImpl.eContainer();
        	Boolean condition2 = sourceView.eContainer().eContainer().toString().equals(subSystemImplImpl.getName());
        	return condition1&&condition2;
    	}
    	
    	System.out.println("获取AccessChannel创建的前提条件出现问题");
    	return false;
    	
    }
    
    /**
     * 创建活动图的控制流
     * 目的：找到初始活动和结束活动，创建初始边和结束边
     * @param self
     * @return
     */
    public ActivitySubComponent get_Init_Final_Activity(SubSystemImpl self, String type) {
//    	System.out.println("进入get_Init_Final_Activity");
    	SubSystemImplImpl subSystemImplImpl = (SubSystemImplImpl) self;
    	ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) subSystemImplImpl.getActivityInteractions();
    	ScheduleImpl scheduleImpl = (ScheduleImpl) activityInteractionsImpl.getActivityControlFlow();
		EList<ActivitySubComponent> activitySubComponents = scheduleImpl.getActivitys();
		if("Init".equals(type)) 
			return activitySubComponents.get(0);
		else if("Final".equals(type))
			return activitySubComponents.get(activitySubComponents.size()-1);

		return null;
	}
    
    /**
     * 创建活动图的控制流
     * 目的：找到当前活动的下一个活动
     */
    public ActivitySubComponent getNextActivity(ActivitySubComponent self) {
//    	System.out.println(self);
    	ActivitySubComponentImpl activityTypeImpl = (ActivitySubComponentImpl) self;
    	EObject eContainerEObject = activityTypeImpl.eContainer();
//    	System.out.println(eContainerEObject);
    	if(eContainerEObject instanceof ActivityInteractionsImpl) {
    		ActivityInteractionsImpl activityInteractionsImpl = (ActivityInteractionsImpl) eContainerEObject;
    		ScheduleImpl scheduleImpl = (ScheduleImpl) activityInteractionsImpl.getActivityControlFlow();
    		EList<ActivitySubComponent> activitySubComponents = scheduleImpl.getActivitys();
    		for (int i = 0; i < activitySubComponents.size(); i++) {
    			ActivitySubComponent activitySubComponent = activitySubComponents.get(i);
    			if(activitySubComponent.equals(self) && i != activitySubComponents.size()-1) {
    				return activitySubComponents.get(i+1);
    			}
			}
    	}
		return null;
    }
    
    /**
     * 获取状态机的初始状态子组件
     * @param self
     * @return
     */
    public StateSubComponent getInitStateSubComponent(ActivityImpl self) {
    	ActivityImplImpl activityImplImpl = (ActivityImplImpl) self;
    	StateMachineImpl stateMachineImpl = (StateMachineImpl) activityImplImpl.getStateMachine();
    	if(stateMachineImpl == null) return null;
    	EList<StateSubComponent> stateSubComponents = stateMachineImpl.getOwnedStateSubComponent();
    	for(StateSubComponent stateSubComponent : stateSubComponents) {
    		StateSubComponentImpl stateSubComponentImpl = (StateSubComponentImpl) stateSubComponent;
    		if(stateSubComponentImpl.isIsInitState()) 
    			return stateSubComponent;
    	}
		return null;
    }
    
    /**
     * 获取DataComponentImpl中的所有地址绑定
     * @param self
     * @return
     */
    public List<AddressBinding> getDataImplAddressBinding(DataComponentImpl self) {
    	List<AddressBinding> res = new ArrayList<>();
//    	System.out.println("进入getDataImplAddressBinding");
    	DataComponentImplImpl dataComponentImplImpl = (DataComponentImplImpl) self;
    	EList<AddressBinding> addressBindings = dataComponentImplImpl.getAddressBindings();
    	for(AddressBinding addressBinding : addressBindings) {
    		res.add(addressBinding);
    	}
//    	System.out.println(addressBindings);
		return res; 
    	
    }
    
    /**
     * 获取DataComponentImpl中的每条地址绑定的内容
     * @param self
     * @return
     */
    public String getAddressBindingContent(AddressBinding self) {
    	AddressBindingImpl addressBindingImpl = (AddressBindingImpl) self;
    	StringBuilder resStringBuilder = new StringBuilder();
    	VariableImpl variableImpl = (VariableImpl) addressBindingImpl.getVariableName();
    	resStringBuilder.append(variableImpl.getName() + " : " + addressBindingImpl.getAddress());
    	
		return resStringBuilder.toString();
    	
    }
    
}
